home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Programming / vbcc / statements.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  30KB  |  879 lines

  1. /*  $VER: vbcc (statements.c) V0.4  */
  2.  
  3. #include "vbc.h"
  4.  
  5. static char FILE_[]=__FILE__;
  6.  
  7. int cont_label=0;
  8. int test_assignment(struct Typ *,np);
  9.  
  10. #define cr()
  11. #ifndef cr
  12. void cr(void)
  13. /*  tested Registerbelegung */
  14. {
  15.     int i;
  16.     for(i=0;i<=MAXR;i++)
  17.         if(regs[i]!=regsa[i]) {error(149,regnames[i]);regs[i]=regsa[i];}
  18. }
  19. #endif
  20. void statement(void)
  21. /*  bearbeitet ein statement                                    */
  22. {
  23.     char *merk;
  24.     cr();
  25.     killsp();
  26.     if(*s=='{'){
  27.         enter_block();
  28.         if(nesting>0) local_offset[nesting]=local_offset[nesting-1];
  29.         compound_statement();leave_block();return;}
  30.     merk=s;
  31.     cpbez(buff,0);
  32.     if(!strcmp("if",buff)){if_statement();return;}
  33.     if(!strcmp("switch",buff)){switch_statement();return;}
  34.     if(!strcmp("for",buff)){for_statement();return;}
  35.     if(!strcmp("while",buff)){while_statement();return;}
  36.     if(!strcmp("do",buff)){do_statement();return;}
  37.     if(!strcmp("goto",buff)){goto_statement();return;}
  38.     if(!strcmp("continue",buff)){continue_statement();return;}
  39.     if(!strcmp("break",buff)){break_statement();return;}
  40.     if(!strcmp("return",buff)){return_statement();return;}
  41.     if(!strcmp("case",buff)){labeled_statement();return;}
  42.     killsp();if(*s==':'){labeled_statement();return;}
  43.     /*  fehlt Aufruf der anderen statements */
  44.     s=merk;
  45.     expression_statement();
  46. }
  47. void labeled_statement(void)
  48. /*  bearbeitet labeled_statement                                */
  49. {
  50.     struct llist *lp;int def=0;
  51.     nocode=0;
  52.     if(*s==':'){
  53.         s++;
  54.         if(!*buff){error(130);return;}
  55.         if(!strcmp("default",buff)){def=1;lp=0;} else lp=find_label(buff);
  56.         if(lp&&lp->flags&LABELDEFINED){error(131,buff);return;}
  57.         if(!lp) lp=add_label(buff);
  58.         lp->flags|=LABELDEFINED;
  59.         lp->switch_count=0;
  60.         if(def){
  61.             if(switch_act==0) error(150);
  62.             lp->flags|=LABELDEFAULT;
  63.             lp->switch_count=switch_act;
  64.         }
  65.         gen_label(lp->label);
  66.         afterlabel=0;
  67.     }else{
  68.         /*  case    */
  69.         np tree;struct llist *lp;
  70.         tree=expression();
  71.         killsp();
  72.         if(*s==':'){s++;killsp();} else error(70);
  73.         if(!switch_count){
  74.             error(132);
  75.         }else{
  76.             if(!tree||!type_expression(tree)){
  77.             }else{
  78.                 if(tree->flags!=CEXPR||tree->sidefx){
  79.                     error(133);
  80.                 }else{
  81.                     if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  82.                         error(134);
  83.                     }else{
  84.                         lp=add_label(empty);
  85.                         lp->flags=LABELDEFINED;
  86.                         lp->switch_count=switch_act;
  87.                         eval_constn(tree);
  88.                         if(switch_typ==CHAR) lp->val.vchar=vchar;
  89.                         if(switch_typ==(UNSIGNED|CHAR)) lp->val.vuchar=vuchar;
  90.                         if(switch_typ==SHORT) lp->val.vshort=vshort;
  91.                         if(switch_typ==(UNSIGNED|SHORT)) lp->val.vushort=vushort;
  92.                         if(switch_typ==INT) lp->val.vint=vint;
  93.                         if(switch_typ==(UNSIGNED|INT)) lp->val.vuint=vuint;
  94.                         if(switch_typ==LONG) lp->val.vlong=vlong;
  95.                         if(switch_typ==(UNSIGNED|LONG)) lp->val.vulong=vulong;
  96.                         if(switch_typ==POINTER) lp->val.vpointer=vpointer;
  97.                         gen_label(lp->label);
  98.                     }
  99.                 }
  100.             }
  101.         }
  102.         if(tree) free_expression(tree);
  103.     }
  104.     cr();
  105.     killsp();
  106.     if(*s!='}') statement();
  107. }
  108. void if_statement(void)
  109. /*  bearbeitet if_statement                                     */
  110. {
  111.     int ltrue,lfalse,lout,cexpr,cm;char *merk,buff[MAXI];
  112.     np tree;struct IC *new;
  113.     killsp(); if(*s=='(') s++; else error(151);
  114.     killsp();cm=nocode;
  115.     tree=expression();
  116.     if(!tree) {error(135);
  117.     }else{
  118.         ltrue=++label;lfalse=++label;
  119.         if(type_expression(tree)){
  120.             tree=makepointer(tree);
  121.             if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER)
  122.                 {error(136);
  123.             }else{
  124.                 if(tree->flags==ASSIGN) error(164);
  125.                 gen_IC(tree,ltrue,lfalse);
  126.                 if(tree->flags==CEXPR){
  127.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  128.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0))&&zuleqto(vulong,ul2zul(0UL))) cexpr=2; else cexpr=1;
  129.                 }else cexpr=0;
  130.                 if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  131.                 if(tree->o.flags&&!cexpr){
  132.                     new=mymalloc(ICS);
  133.                     new->code=TEST;
  134.                     new->q1=tree->o;
  135.                     new->q2.flags=new->z.flags=0;
  136.                     new->typf=tree->ntyp->flags;
  137.                     add_IC(new);
  138.                     new=mymalloc(ICS);
  139.                     new->code=BEQ;
  140.                     new->typf=lfalse;
  141.                     add_IC(new);
  142.                 }
  143.                 if(cexpr==2){
  144.                     new=mymalloc(ICS);
  145.                     new->code=BRA;
  146.                     new->typf=lfalse;
  147.                     add_IC(new);
  148.                 }
  149.             }
  150.         }
  151.         free_expression(tree);
  152.     }
  153.     killsp(); if(*s==')') s++; else error(59);
  154.     if(cexpr==2) nocode=1;
  155.     if(!cexpr&&!tree->o.flags) gen_label(ltrue);
  156.     statement();
  157.     killsp();
  158.     merk=s;
  159.     cpbez(buff,0);
  160.     if(strcmp("else",buff)) {s=merk;nocode=cm;if(cexpr!=1) gen_label(lfalse);return;}
  161.     lout=++label;
  162.     if(cexpr!=2){
  163.         new=mymalloc(ICS);
  164.         new->code=BRA;
  165.         new->typf=lout;
  166.         add_IC(new);
  167.     }
  168.     if(cexpr!=1) {nocode=cm;gen_label(lfalse);}
  169.     if(cexpr==1) nocode=1; else nocode=cm;
  170.     statement();
  171.     nocode=cm;
  172.     if(cexpr!=2) gen_label(lout);
  173.     cr();
  174. }
  175. void switch_statement(void)
  176. /*  bearbeitet switch_statement                                 */
  177. {
  178.     np tree;int merk_typ,merk_count,merk_break;
  179.     struct IC *merk_fic,*merk_lic,*new;struct llist *lp,*l1,*l2;
  180.     killsp();
  181.     if(*s=='('){s++;killsp();} else error(151);
  182.     tree=expression(); killsp();
  183.     if(*s==')'){s++;killsp();} else error(59);
  184.     merk_typ=switch_typ;merk_count=switch_act;merk_break=break_label;
  185.     if(!tree){
  186.         error(137);
  187.     }else{
  188.         if(!type_expression(tree)){
  189.         }else{
  190.             if((tree->ntyp->flags&NQ)<CHAR||(tree->ntyp->flags&NQ)>LONG){
  191.                 error(138);
  192.             }else{
  193.                 int m1,m2,m3,def=0,rm,minflag;
  194.                 zlong l,ml,s;zulong ul,mul,us;
  195.                 if(tree->flags==ASSIGN) error(164);
  196.                 m3=break_label=++label;m1=switch_act=++switch_count;
  197.                 m2=switch_typ=tree->ntyp->flags&NU;
  198.                 gen_IC(tree,0,0);
  199.                 if((tree->o.flags&(DREFOBJ|SCRATCH))!=SCRATCH){
  200.                     new=mymalloc(ICS);
  201.                     new->code=ASSIGN;
  202.                     new->q1=tree->o;
  203.                     new->q2.flags=0;
  204.                     new->q2.val.vlong=sizetab[m2&NQ];
  205.                     get_scratch(&new->z,m2,0,0);
  206.                     new->typf=m2;
  207.                     tree->o=new->z;
  208.                     add_IC(new);
  209.                 }
  210.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){
  211.                     int r=tree->o.reg;
  212.                     rm=regs[r];
  213.                     regs[r]=regsa[r];
  214.                 }
  215.                 merk_fic=first_ic;merk_lic=last_ic;
  216.                 first_ic=last_ic=0;
  217.                 statement();
  218.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)) regs[tree->o.reg]=rm;
  219.                 minflag=0;s=l2zl(0L);us=ul2zul(0UL);
  220.                 for(l1=first_llist;l1;l1=l1->next){
  221.                     if(l1->switch_count!=m1) continue;
  222.                     if(l1->flags&LABELDEFAULT){
  223.                         if(def) error(139);
  224.                         def=l1->label;
  225.                         continue;
  226.                     }
  227.                     lp=0;minflag&=~1;
  228.                     for(l2=first_llist;l2;l2=l2->next){
  229.                         if(l2->switch_count!=m1) continue;
  230.                         if(l2->flags&LABELDEFAULT) continue;
  231.                         eval_const(&l2->val,m2);
  232.                         if(minflag&2){
  233.                             if(m2&UNSIGNED){
  234.                                 if(zulleq(vulong,mul)||zuleqto(vulong,mul)) continue;
  235.                             }else{
  236.                                 if(zlleq(vlong,ml)||zleqto(vlong,ml)) continue;
  237.                             }
  238.                         }
  239.                         if(minflag&1){
  240.                             if(m2&UNSIGNED){
  241.                                 if(!(minflag&4)&&zuleqto(vulong,ul)){ error(201);minflag|=4;}
  242.                                 if(zulleq(vulong,ul)){lp=l2;ul=vulong;}
  243.                             }else{
  244.                                 if(!(minflag&4)&&zleqto(vlong,l)){ error(201);minflag|=4;}
  245.                                 if(zlleq(vlong,l)){lp=l2;l=vlong;}
  246.                             }
  247.                         }else{
  248.                             minflag|=1;
  249.                             l=vlong;
  250.                             ul=vulong;
  251.                             lp=l2;
  252.                         }
  253.                     }
  254.                     if(!lp) continue;
  255.                     ml=l;mul=ul;minflag|=2;
  256.                     if(SWITCHSUBS){
  257.                         new=mymalloc(ICS);
  258.                         new->line=0;
  259.                         new->file=0;
  260.                         new->typf=m2;
  261.                         new->code=SUB;
  262.                         new->q1=tree->o;
  263.                         new->z=tree->o;
  264.                         new->q2.flags=KONST;
  265.                         eval_const(&lp->val,m2);
  266.                         vlong=zlsub(vlong,s);
  267.                         vulong=zulsub(vulong,us);
  268.                         vint=zl2zi(vlong);
  269.                         vshort=zl2zs(vlong);
  270.                         vchar=zl2zc(vlong);
  271.                         vuint=zul2zui(vulong);
  272.                         vushort=zul2zus(vulong);
  273.                         vuchar=zul2zuc(vulong);
  274.                         insert_const2(&new->q2.val,m2);
  275.                         new->q1.am=new->q2.am=new->z.am=0;
  276.                         s=l;us=ul;
  277.                         new->prev=merk_lic;
  278.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  279.                         merk_lic=new;
  280.                         new=mymalloc(ICS);
  281.                         new->line=0;
  282.                         new->file=0;
  283.                         new->typf=m2;
  284.                         new->code=TEST;
  285.                         new->q1=tree->o;
  286.                         new->q2.flags=new->z.flags=0;
  287.                         new->prev=merk_lic;
  288.                         new->q1.am=new->q2.am=new->z.am=0;
  289.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  290.                         merk_lic=new;
  291.                     }else{
  292.                         new=mymalloc(ICS);
  293.                         new->line=0;
  294.                         new->file=0;
  295.                         new->code=COMPARE;
  296.                         new->typf=m2;
  297.                         new->q1=tree->o;
  298.                         new->q2.flags=KONST;
  299.                         new->q2.val=lp->val;
  300.                         new->z.flags=0;
  301.                         new->prev=merk_lic;
  302.                         new->q1.am=new->q2.am=new->z.am=0;
  303.                         if(merk_lic) merk_lic->next=new; else merk_fic=new;
  304.                         merk_lic=new;
  305.                     }
  306.                     new=mymalloc(ICS);
  307.                     new->line=0;
  308.                     new->file=0;
  309.                     new->code=BEQ;
  310.                     new->typf=lp->label;
  311.                     new->q1.flags=new->q2.flags=new->z.flags=0;
  312.                     new->prev=merk_lic;
  313.                     new->q1.am=new->q2.am=new->z.am=0;
  314.                     merk_lic->next=new;
  315.                     merk_lic=new;
  316.                 }
  317.                 if((tree->o.flags&(SCRATCH|REG))==(SCRATCH|REG)){   /* free_reg(tree->o.reg); */
  318.                     new=mymalloc(ICS);
  319.                     new->line=0;
  320.                     new->file=0;
  321.                     new->code=FREEREG;new->typf=0;
  322.                     new->q2.flags=new->z.flags=0;
  323.                     new->q1.flags=REG;
  324.                     new->q1.reg=tree->o.reg;
  325.                     new->prev=merk_lic;
  326.                     new->q1.am=new->q2.am=new->z.am=0;
  327.                     if(merk_lic) merk_lic->next=new; else merk_fic=new;
  328.                     merk_lic=new;
  329.                     regs[tree->o.reg]=regsa[tree->o.reg];
  330.                 }
  331.                 new=mymalloc(ICS);
  332.                 new->line=0;
  333.                 new->file=0;
  334.                 new->code=BRA;
  335.                 if(def) new->typf=def; else new->typf=m3;
  336.                 new->q1.flags=new->q2.flags=new->z.flags=0;
  337.                 if(merk_lic) merk_lic->next=new; else merk_fic=new;
  338.                 new->prev=merk_lic;
  339.                 first_ic->prev=new;
  340.                 new->next=first_ic;
  341.                 new->q1.am=new->q2.am=new->z.am=0;
  342.                 first_ic=merk_fic;
  343.                 gen_label(m3);
  344.             }
  345.         }
  346.     }
  347.     switch_typ=merk_typ;switch_act=merk_count;break_label=merk_break;
  348.     if(tree) free_expression(tree);
  349.     cr();
  350. }
  351. void repair_tree(np p)
  352. /*  Bearbeitet einen Ausdruckbaum so, dass er ein zweites Mal   */
  353. /*  mit gen_IC erzeugt werden kann.                             */
  354. {
  355.     if(p->left) repair_tree(p->left);
  356.     if(p->right) repair_tree(p->right);
  357.     if(p->flags==IDENTIFIER||p->flags==(IDENTIFIER|256))
  358.         p->o.v=find_var(p->identifier,0);
  359. }
  360. void while_statement(void)
  361. /*  bearbeitet while_statement                                  */
  362. {
  363.     np tree;int lloop,lin,lout,cm,cexpr,contm,breakm;
  364.     struct IC *new,*mic; int line;char *file;
  365.     killsp();
  366.     if(*s=='(') {s++;killsp();} else error(151);
  367.     tree=expression();
  368.     cexpr=0;
  369.     if(tree){
  370.         if(type_expression(tree)){
  371.             tree=makepointer(tree);
  372.             if(!arith(tree->ntyp->flags&NQ)&&(tree->ntyp->flags&NQ)!=POINTER){
  373.                 error(140);
  374.                 cexpr=-1;
  375.             }else{
  376.                 if(tree->flags==ASSIGN) error(164);
  377.                 if(tree->flags==CEXPR){
  378.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  379.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  380.                     if(cexpr==1) error(152);
  381.                 }
  382.             }
  383.         }else cexpr=-1;
  384.     } else error(141);
  385.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  386.     contm=cont_label;breakm=break_label;
  387.     if(!cexpr||tree->sidefx) cont_label=lin; else cont_label=lloop;
  388.     if(!cexpr||tree->sidefx){
  389.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  390.             gen_IC(tree,lloop,lout);
  391.             if(tree->o.flags){
  392.                 new=mymalloc(ICS);
  393.                 new->code=TEST;
  394.                 new->typf=tree->ntyp->flags&NU;
  395.                 new->q1=tree->o;
  396.                 new->q2.flags=new->z.flags=0;
  397.                 add_IC(new);
  398.                 new=mymalloc(ICS);
  399.                 new->code=BEQ;
  400.                 new->typf=lout;
  401.                 add_IC(new);
  402.             }
  403.             repair_tree(tree);
  404.         }else{
  405.             new=mymalloc(ICS);
  406.             new->code=BRA;
  407.             new->typf=lin;
  408.             add_IC(new);
  409.         }
  410.     }
  411.     if(cexpr==1){
  412.         new=mymalloc(ICS);
  413.         new->code=BRA;
  414.         new->typf=lout;
  415.         add_IC(new);
  416.     }else gen_label(lloop);
  417.     line=last_ic->line;file=last_ic->file;
  418.     cm=nocode;break_label=lout;
  419.     if(cexpr==1) nocode=1;
  420.     currentpri*=looppri;
  421.     killsp();
  422.     if(*s==')') {s++;killsp();} else error(59);
  423.     statement();
  424.     mic=last_ic;
  425.     nocode=cm;cont_label=contm;break_label=breakm;
  426.     if(!cexpr||tree->sidefx) gen_label(lin);
  427.     if(tree&&cexpr>=0){
  428.         if(cexpr!=1||tree->sidefx){
  429.             gen_IC(tree,lloop,lout);
  430.             if((tree->o.flags&SCRATCH)&&cexpr) free_reg(tree->o.reg);
  431.         }
  432.         if(tree->o.flags&&!cexpr){
  433.             new=mymalloc(ICS);
  434.             new->code=TEST;
  435.             new->typf=tree->ntyp->flags&NU;
  436.             new->q1=tree->o;
  437.             new->q2.flags=new->z.flags=0;
  438.             add_IC(new);
  439.             new=mymalloc(ICS);
  440.             new->code=BNE;
  441.             new->typf=lloop;
  442.             add_IC(new);
  443.         }
  444.         if(cexpr==2){
  445.             new=mymalloc(ICS);
  446.             new->code=BRA;
  447.             new->typf=lloop;
  448.             add_IC(new);
  449.         }
  450.     }
  451.     if(tree) free_expression(tree);
  452.     for(mic=mic->next;mic;mic=mic->next){
  453.       mic->line=line;mic->file=file;
  454.     }
  455.     gen_label(lout);
  456.     currentpri/=looppri;
  457.     cr();
  458. }
  459. void for_statement(void)
  460. /*  bearbeitet for_statement                                    */
  461. {
  462.     np tree1=0,tree2=0,tree3=0;int lloop,lin,lout,cm,cexpr,contm,breakm;
  463.     struct IC *new,*mic;int line;char *file;
  464.     killsp();
  465.     if(*s=='(') {s++;killsp();} else error(59);
  466.     if(*s!=';') tree1=expression();
  467.     if(tree1){
  468.         if(tree1->flags==POSTINC) tree1->flags=PREINC;
  469.         if(tree1->flags==POSTDEC) tree1->flags=PREDEC;
  470.         if(type_expression(tree1)){
  471.             if(tree1->sidefx){
  472.                 gen_IC(tree1,0,0);
  473.                 if(tree1&&(tree1->o.flags&SCRATCH)) free_reg(tree1->o.reg);
  474.             }else{error(153);}
  475.         }
  476.         free_expression(tree1);
  477.     }
  478.     cexpr=0;
  479.     killsp();
  480.     if(*s==';') {s++;killsp();} else error(54);
  481.     if(*s!=';') {tree2=expression();killsp();} else {cexpr=2;}
  482.     if(*s==';') {s++;killsp();} else error(54);
  483.     if(*s!=')') tree3=expression();
  484.     killsp();
  485.     if(*s==')') {s++;killsp();} else error(59);
  486.     if(tree3){
  487.         if(!type_expression(tree3)){
  488.             free_expression(tree3);
  489.             tree3=0;
  490.         }
  491.     }
  492.     if(tree2){
  493.         if(type_expression(tree2)){
  494.             tree2=makepointer(tree2);
  495.             if(!arith(tree2->ntyp->flags&NQ)&&(tree2->ntyp->flags&NQ)!=POINTER){
  496.                 error(142);
  497.                 cexpr=-1;
  498.             }else{
  499.                 if(tree2->flags==ASSIGN) error(164);
  500.                 if(tree2->flags==CEXPR){
  501.                     eval_const(&tree2->val,tree2->ntyp->flags&NU);
  502.                     if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))) cexpr=1; else cexpr=2;
  503.                     if(cexpr==1) error(152);
  504.                 }
  505.             }
  506.         }else cexpr=-1;
  507.     }
  508.     lloop=++label;lin=++label;lout=++label;cm=nocode;
  509.     contm=cont_label;breakm=break_label;
  510.     cont_label=++label;break_label=lout;
  511.     if(!cexpr||(tree2&&tree2->sidefx)){
  512.         if(c_flags_val[0].l&2){ /*  bei Optimierung */
  513.             gen_IC(tree2,lloop,lout);
  514.             if(tree2->o.flags){
  515.                 new=mymalloc(ICS);
  516.                 new->code=TEST;
  517.                 new->typf=tree2->ntyp->flags&NU;
  518.                 new->q1=tree2->o;
  519.                 new->q2.flags=new->z.flags=0;
  520.                 add_IC(new);
  521.                 new=mymalloc(ICS);
  522.                 new->code=BEQ;
  523.                 new->typf=lout;
  524.                 add_IC(new);
  525.             }
  526.             repair_tree(tree2);
  527.         }else{
  528.             new=mymalloc(ICS);
  529.             new->code=BRA;
  530.             new->typf=lin;
  531.             add_IC(new);
  532.         }
  533.     }
  534.     if(cexpr==1){
  535.         new=mymalloc(ICS);
  536.         new->code=BRA;
  537.         new->typf=lout;
  538.         add_IC(new);
  539.     }else gen_label(lloop);
  540.     line=last_ic->line;file=last_ic->file;
  541.     cm=nocode;
  542.     if(cexpr==1) nocode=1;
  543.     currentpri*=looppri;
  544.     statement();
  545.     mic=last_ic;
  546.     nocode=cm;
  547.     gen_label(cont_label);
  548.     cont_label=contm;break_label=breakm;
  549.     if(tree3){
  550.         if(tree3->flags==POSTINC) tree3->flags=PREINC;
  551.         if(tree3->flags==POSTDEC) tree3->flags=PREDEC;
  552.         if(tree3->sidefx){
  553.             gen_IC(tree3,0,0);
  554.             if(tree3&&(tree3->o.flags&SCRATCH)) free_reg(tree3->o.reg);
  555.         }else error(153);
  556.         free_expression(tree3);
  557.     }
  558.     if(!cexpr||(tree2&&tree2->sidefx)) gen_label(lin);
  559.     if(tree2&&cexpr>=0){
  560.         if(cexpr!=1||tree2->sidefx){
  561.             gen_IC(tree2,lloop,lout);
  562.             if((tree2->o.flags&SCRATCH)&&cexpr) free_reg(tree2->o.reg);
  563.         }
  564.         if(tree2->o.flags&&!cexpr){
  565.             new=mymalloc(ICS);
  566.             new->code=TEST;
  567.             new->typf=tree2->ntyp->flags&NU;
  568.             new->q1=tree2->o;
  569.             new->q2.flags=new->z.flags=0;
  570.             add_IC(new);
  571.             new=mymalloc(ICS);
  572.             new->code=BNE;
  573.             new->typf=lloop;
  574.             add_IC(new);
  575.         }
  576.         if(cexpr==2){
  577.             new=mymalloc(ICS);
  578.             new->code=BRA;
  579.             new->typf=lloop;
  580.             add_IC(new);
  581.         }
  582.     }
  583.     if(!tree2&&cexpr==2){
  584.         new=mymalloc(ICS);
  585.         new->code=BRA;
  586.         new->typf=lloop;
  587.         add_IC(new);
  588.     }
  589.     if(tree2) free_expression(tree2);
  590.     for(mic=mic->next;mic;mic=mic->next){
  591.       mic->line=line;mic->file=file;
  592.     }
  593.     gen_label(lout);
  594.     currentpri/=looppri;
  595.     cr();
  596. }
  597. void do_statement(void)
  598. /*  bearbeitet do_statement                                     */
  599. {
  600.     np tree;int lloop,lout,contm,breakm;
  601.     struct IC *new;
  602.     lloop=++label;lout=++label;currentpri*=looppri;
  603.     gen_label(lloop);
  604.     breakm=break_label;contm=cont_label;cont_label=++label;break_label=lout;
  605.     statement();
  606.     killsp();
  607.     gen_label(cont_label);cont_label=contm;break_label=breakm;
  608.     cpbez(buff,0);killsp();
  609.     if(strcmp("while",buff)) error(154);
  610.     if(*s=='(') {s++;killsp();} else error(151);
  611.     tree=expression();
  612.     if(tree){
  613.         if(type_expression(tree)){
  614.             tree=makepointer(tree);
  615.             if(arith(tree->ntyp->flags&NQ)||(tree->ntyp->flags&NQ)==POINTER){
  616.                 if(tree->flags==ASSIGN) error(164);
  617.                 if(tree->flags==CEXPR){
  618.                     eval_const(&tree->val,tree->ntyp->flags&NU);
  619.                     if(tree->sidefx) gen_IC(tree,0,0);
  620.                     if(!zdeqto(vdouble,d2zd(0.0))){
  621.                         new=mymalloc(ICS);
  622.                         new->code=BRA;
  623.                         new->typf=lloop;
  624.                         add_IC(new);
  625.                     }
  626.                 }else{
  627.                     gen_IC(tree,lloop,lout);
  628.                     if(tree->o.flags){
  629.                         new=mymalloc(ICS);
  630.                         new->code=TEST;
  631.                         new->typf=tree->ntyp->flags&NU;
  632.                         new->q1=tree->o;
  633.                         new->q2.flags=new->z.flags=0;
  634.                         add_IC(new);
  635.                         new=mymalloc(ICS);
  636.                         new->code=BNE;
  637.                         new->typf=lloop;
  638.                         add_IC(new);
  639.                     }
  640.                 }
  641.             }else error(143);
  642.         }
  643.         free_expression(tree);
  644.     }
  645.     killsp();
  646.     if(*s==')') {s++;killsp();} else error(59);
  647.     if(*s==';') {s++;killsp();} else error(54);
  648.     gen_label(lout);
  649.     currentpri/=looppri;
  650.     cr();
  651. }
  652. void goto_statement(void)
  653. /*  bearbeitet goto_statement                                   */
  654. {
  655.     struct llist *lp;
  656.     struct IC *new;
  657.     killsp();cpbez(buff,1);
  658.     if(!*buff) error(144);
  659.     lp=find_label(buff);
  660.     if(!lp) lp=add_label(buff);
  661.     lp->flags|=LABELUSED;
  662.     new=mymalloc(ICS);
  663.     new->typf=lp->label;
  664.     new->code=BRA;
  665.     new->typf=lp->label;
  666.     add_IC(new);
  667.     killsp();
  668.     if(*s==';'){s++;killsp();} else error(54);
  669.     cr();
  670.     goto_used=1;
  671. }
  672. void continue_statement(void)
  673. /*  bearbeitet continue_statement                               */
  674. {
  675.     struct IC *new;
  676.     if(cont_label==0){error(145);return;}
  677.     new=mymalloc(ICS);
  678.     new->code=BRA;
  679.     new->typf=cont_label;
  680.     add_IC(new);
  681.     killsp();
  682.     if(*s==';') {s++;killsp();} else error(54);
  683.     cr();
  684. }
  685. void break_statement(void)
  686. /*  bearbeitet break_statement                                  */
  687. {
  688.     struct IC *new;
  689.     if(break_label==0){error(146);return;}
  690.     new=mymalloc(ICS);
  691.     new->code=BRA;
  692.     new->typf=break_label;
  693.     add_IC(new);
  694.     killsp();
  695.     if(*s==';') {s++;killsp();} else error(54);
  696.     cr();
  697. }
  698. static void check_auto_return(np tree)
  699. /*  Testet, ob Knoten Adresse einer automatischen Variable ist. */
  700. {
  701.     if((tree->flags==ADDRESS||tree->flags==ADDRESSS||tree->flags==ADDRESSA)&&tree->left->flags==IDENTIFIER){
  702.         struct Var *v;
  703.         if(v=find_var(tree->left->identifier,0)){
  704.             if(v->storage_class==AUTO) error(224);
  705.         }
  706.     }
  707. }
  708. extern int has_return;
  709. void return_statement(void)
  710. /*  bearbeitet return_statement                                 */
  711. /*  SETRETURN hat Groesse in q2.reg und z.reg==freturn(rtyp)    */
  712. {
  713.     np tree;
  714.     struct IC *new;
  715.     has_return=1;
  716.     killsp();
  717.     if(*s!=';'){
  718.         if(tree=expression()){
  719.             if(!return_typ){
  720.                 if(type_expression(tree)){
  721.                     tree=makepointer(tree);
  722.                     if((tree->ntyp->flags&NQ)!=VOID) error(155);
  723.                         else error(225);
  724.                     gen_IC(tree,0,0);
  725.                     if(tree->o.flags&SCRATCH) free_reg(tree->o.reg);
  726.                 }
  727.             }else{
  728.                 if(type_expression(tree)){
  729.                     tree=makepointer(tree);
  730.                     if(tree->flags==ADD||tree->flags==SUB){
  731.                         check_auto_return(tree->left);
  732.                         check_auto_return(tree->right);
  733.                     }else{
  734.                         check_auto_return(tree);
  735.                     }
  736.                     if(!test_assignment(return_typ,tree)){free_expression(tree);return;}
  737.                     gen_IC(tree,0,0);
  738.                     convert(tree,return_typ->flags&NU);
  739. #ifdef OLDPARMS   /*  alte CALL/RETURN-Methode    */
  740.                     new=mymalloc(ICS);
  741.                     new->code=ASSIGN;
  742.                     new->typf=return_typ->flags&NU;
  743.                     new->q1=tree->o;
  744.                     new->q2.flags=0;
  745.                     new->q2.val.vlong=szof(return_typ);
  746.                     if(freturn(return_typ)){
  747.                         new->z.flags=SCRATCH|REG;
  748.                         new->z.reg=freturn(return_typ);
  749.                         if(!regs[new->z.reg]){
  750.                             struct IC *alloc=mymalloc(ICS);
  751.                             alloc->code=ALLOCREG;
  752.                             alloc->q1.flags=REG;
  753.                             alloc->q2.flags=alloc->z.flags=0;
  754.                             alloc->q1.reg=new->z.reg;
  755.                             regs[new->z.reg]=1;
  756.                             add_IC(alloc);
  757.                         }
  758.                     }else{
  759.                         new->z.reg=0;
  760.                         new->z.v=return_var;
  761.                         new->z.flags=SCRATCH|VAR;
  762.                         new->z.val.vlong=l2zl(0L);
  763.                     }
  764.                     add_IC(new);
  765.                     /*  das hier ist nicht sehr schoen, aber wie sonst? */
  766.                     if(new->z.flags&SCRATCH&®s[new->z.reg]) free_reg(new->z.reg);
  767. #else
  768.                     new=mymalloc(ICS);
  769.                     if(return_var){ /*  Returnwert ueber Zeiger */
  770.                         new->code=ASSIGN;
  771.                         new->z.flags=VAR|DREFOBJ;
  772.                         new->z.val.vlong=l2zl(0L);
  773.                         new->z.v=return_var;
  774.                     }else{
  775.                         new->code=SETRETURN;
  776.                         new->z.reg=freturn(return_typ);
  777.                         new->z.flags=0;
  778.                     }
  779.                     new->typf=return_typ->flags&NU;
  780.                     new->q1=tree->o;
  781.                     new->q2.flags=0;
  782.                     new->q2.val.vlong=szof(return_typ);
  783.                     add_IC(new);
  784. #endif
  785.                 }
  786.             }
  787.             free_expression(tree);
  788.             killsp();
  789.             if(*s==';') {s++;killsp();} else error(54);
  790.         }else{
  791.             if(return_typ) error(156);
  792.         }
  793.     }else{ s++; if(return_typ) error(156);}
  794.  
  795.     new=mymalloc(ICS);
  796.     new->code=BRA;
  797.     new->typf=return_label;
  798.     add_IC(new);
  799.     cr();
  800. }
  801.  
  802. void expression_statement(void)
  803. /*  bearbeitet expression_statement                             */
  804. {
  805.     np tree;
  806.     killsp();
  807.     if(*s==';') {s++;return;}
  808.     if(tree=expression()){
  809.         if(tree->flags==POSTINC) tree->flags=PREINC;
  810.         if(tree->flags==POSTDEC) tree->flags=PREDEC;
  811.         if(type_expression(tree)){
  812.             if(DEBUG&2){pre(stdout,tree);printf("\n");}
  813.             if(tree->sidefx){
  814.                 gen_IC(tree,0,0);
  815.                 if((tree->o.flags&(SCRATCH|REG))==REG) ierror(0);
  816.                 if(tree&&(tree->o.flags&SCRATCH)) free_reg(tree->o.reg);
  817.             }else{error(153);if(DEBUG&2) prd(stdout,tree->ntyp);}
  818.         }
  819.         free_expression(tree);
  820.     }
  821.     killsp();
  822.     if(*s==';') s++; else error(54);
  823.     cr();
  824. }
  825. void compound_statement(void)
  826. /*  bearbeitet compound_statement (block)                       */
  827. {
  828.     killsp();
  829.     if(*s=='{') s++; else error(157);
  830.     killsp();
  831.     while(declaration(0)){
  832.         var_declaration();
  833.         killsp();
  834.     }
  835.     while(*s!='}'){
  836.         statement();
  837.         killsp();
  838.     }
  839.     s++;/*killsp();*/
  840. }
  841. struct llist *add_label(char *identifier)
  842. /*  Fuegt label in Liste                                        */
  843. {
  844.     struct llist *new;
  845.     new=mymalloc(LSIZE);
  846.     new->next=0;new->label=++label;new->flags=0;
  847.     new->identifier=add_identifier(identifier,strlen(identifier));
  848.     if(first_llist==0){
  849.         first_llist=last_llist=new;
  850.     }else{
  851.         last_llist->next=new;
  852.         last_llist=new;
  853.     }
  854.     return(last_llist); /* return(new) sollte aequiv. sein */
  855. }
  856. struct llist *find_label(char *identifier)
  857. /*  Sucht Label, gibt Zeiger auf llist oder 0 beu Fehler zurueck    */
  858. {
  859.     struct llist *p;
  860.     p=first_llist;
  861.     while(p){
  862.         if(!strcmp(p->identifier,identifier)) return(p);
  863.         p=p->next;
  864.     }
  865.     return(0);
  866. }
  867. void free_llist(struct llist *p)
  868. /*  Gibt llist frei                                             */
  869. {
  870.     struct llist *merk;
  871.     while(p){
  872.         merk=p->next;
  873.         if(!(p->flags&LABELDEFINED)) error(147,p->identifier);
  874.         if(!(p->flags&LABELUSED)&&!p->switch_count) error(148,p->identifier);
  875.         free(p);
  876.         p=merk;
  877.     }
  878. }
  879.